<?php

namespace frontend\controllers;

use Yii;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\Alert;
use common\models\Logger;
use common\models\Config;
use common\models\Email;
use common\models\Command;
use common\models\SensorInfo;
use common\models\AllEX;

/**
 * Site controller
 */
class ApiController extends Controller {

    public $build_query = null;

    /**
     * @inheritdoc
     */
    public function behaviors() {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => [],
                'rules' => [
                    [
                        'actions' => [],
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                    [
                        'actions' => [],
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'actions' => [],
                        'allow' => true,
                        'roles' => ['admin'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                // 'logout' => ['post'],
                // 'test' => ['post'],
                ]
            ]
        ];
    }

    /**
     * @inheritdoc
     */
    public function actions() {
        $this->isAPI();
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
            'captcha' => [
                'class' => 'yii\captcha\CaptchaAction',
                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null
            ]
        ];
    }

    /**
     * Displays homepage.
     *
     * @return mixed
     */
    public $enableCsrfValidation = false;

    private function isAPI() {
        $headers = Yii::$app->request->headers;
        if (stristr($headers['accept'], 'application/json') !== false) {
            Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
        } else {
            Yii::$app->response->format = \yii\web\Response::FORMAT_XML;
        }
    }

    public function actionIndex() {
        $data = ['status' => 'success'];
        return $data;
    }

    public function actionAlert() {
        if (!Yii::$app->request->isPost) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Not post request';
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $RawBody = trim(Yii::$app->request->getRawBody());
            $post = json_decode($RawBody, true);
        }
        if (empty($post)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Rawbody not JSON.';
            Logger::warning('Rawbody not JSON.');
            Logger::warning($RawBody);
            return $data;
        }
        $ret = Alert::receive($post);
        if ($ret === false) {
            $data = ['status' => 'fail', 'message' => 'not alertJSON.'];
            Logger::warning('not alertJSON.');
            Logger::warning($RawBody);
        } else {
            if ($ret == 'add') {
                $data = ['status' => 'success', 'message' => 'Added 1 alerts.'];
            } else {
                $data = ['status' => 'success', 'message' => 'Update 1 alerts.'];
            }
        }
        return $data;
    }

    public function actionLoophole() {
        if (!Yii::$app->request->isPost) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Not post request';
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $post = json_decode(Yii::$app->request->getRawBody(), true);
        }
        if (empty($post)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Rawbody not JSON';
            return $data;
        }
        $count = 0;
        foreach ($post as $key => $item) {
            $alert = new Alert();
            $alert->AlertType = $item['AlertType'];
            $alert->SensorID = $item['SensorID'];
            $alert->AlertID = unpack("Q", pack("i*", time(), ($count + 1)))[1];
            $alert->Timestamp = time() * 1000;
            $alert->SrcType = 5;
            $alert->Point = 0;
            if ($alert->AlertType == 7) {
                $alert->Point = 100;
            }
            $alert->ExceptionAlertList = [];
            $alert->AlertFileList = [];
            $alert->AlertIPList = [];
            $alert->AlertURLList = [];
            $alert->HitRegulationList = [];
            $alert->EventList = [$item];
            $alert->Label = $item['ImagePath'];
            $alert->save();
            Email::addAlert($alert);
            $count ++;
        }
        $data = ['status' => 'success', 'message' => 'Added ' . $count . ' alerts.'];
        Logger::info('api/actionLoophole', 'Loophole');
        Logger::info(Yii::$app->request->getRawBody(), 'Loophole');
        return $data;
    }

    public function actionInvestigation() {
        if (!Yii::$app->request->isPost) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Not post request';
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $RawBody = trim(Yii::$app->request->getRawBody());
            $post = json_decode($RawBody, true);
        }
        if (empty($post)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Rawbody not JSON';
            Logger::warning('not alertJSON.');
            Logger::warning($RawBody);
            return $data;
        }

        $command = Command::find()->where(['CommandID' => $post['CommandID']])->one();
        if (empty($command)) {
            $data['status'] = 'fail';
            $data['errorMessage'] = 'Without this command.';
            Logger::warning('Without this command.');
            Logger::warning($post);
        }
        $commandData = $command->data;
        $commandData['Result'] = $post;
        $command->data = $commandData;
        $command->save();
        $data = ['status' => 'success'];
        return $data;
    }

    public function actionConfig() {
        $data = Config::getConfig();
        $data['status'] = 'success';
        return $data;
    }

    public function actionSensorInfo($SensorID = 0, $all = false) {
        if (Yii::$app->request->isGet) {
            $info = SensorInfo::find()->where(['SensorID' => $SensorID])->one();
            if (empty($info)) {
                $data['status'] = 'fail';
                $data['errorMessage'] = 'not SensorInfo.';
            }
            $data['status'] = 'success';
            $data['data'] = $all ? $info : $info->data;
            return $data;
        }
        if (Yii::$app->request->isPost) {
            $RawBody = trim(Yii::$app->request->getRawBody());
            $post = json_decode($RawBody, true);
            if (empty($post)) {
                $data['status'] = 'fail';
                $data['errorMessage'] = 'Rawbody not JSON';
                Logger::warning('not alertJSON.');
                Logger::warning($RawBody);
                return $data;
            }
            if (empty($post['SensorID'])) {
                $data['status'] = 'fail';
                $data['errorMessage'] = 'No SensorID';
                Logger::warning('not alertJSON.');
                Logger::warning($RawBody);
                return $data;
            }
            $info = SensorInfo::find()->where(['SensorID' => $post['SensorID']])->one();
            if (empty($info)) {
                $info = new SensorInfo();
                $info->SensorID = $post['SensorID'];
            }
            $info->data = $post;
            $info->save();
            $data['status'] = 'success';
            return $data;
        }
    }

    //获取告警数量iview
    public function actionGetAlertCount() {
        $this->build_query = AllEX::find();
        $this->query();
        $count = $this->build_query->count();
        return $count;
    }

    //获取告警（高中低）iview
    public function actionGetAlertDegree() {
        $this->build_query = AllEX::find()->select("COUNT(id) as total_count,SUM(case when Degree='high' then 1 else 0 end) as high,SUM(case when Degree='medium' then 1 else 0 end) as medium,SUM(case when Degree='low' then 1 else 0 end) as low");
        $this->query();
        $degree = $this->build_query->asArray()->one();
        return $degree;
    }

    //获取分组统计的资产（风险资产）iview
    public function actionGetAssetsCount() {
        $this->build_query = AllEX::find()->select("SensorIP asset_ip,SUM(case when Degree='high' then 1 else 0 end) as high_count,SUM(case when Degree='medium' then 1 else 0 end) as medium_count,SUM(case when Degree='low' then 1 else 0 end) as low_count");
        $this->query();
        $assets = $this->build_query->groupBy('asset_ip')->asArray()->all();
        return $assets;
    }

    //获取资产（风险资产）iview
    public function actionGetAssets() {
        $this->build_query = AllEX::find()->select("SensorIP asset_ip");
        $this->query();
        $assets = $this->build_query->groupBy('asset_ip')->asArray()->all();
        return $assets;
    }

    //获取威胁类型 iview
    public function actionGetAlertType() {
        $this->build_query = AllEX::find()->select("SensorIP asset_ip");
        $this->query();
        $assets = $this->build_query->groupBy('asset_ip')->asArray()->all();
        return $assets;
    }

    private function query() {
        $get = Yii::$app->request->get();
        $tag = 0;
        if (array_key_exists('stime', $get) && array_key_exists('etime', $get)) {
            $this->build_query->where(['>', 'created_at', $get['stime']])->andWhere(['<=', 'created_at', $get['etime']]);
            $tag = 1;
        }
        if (array_key_exists('status', $get) && $get['status']) {
            if ($tag == 1) {
                $this->build_query->andWhere(['IN', 'status', [0, 1]]);
            } else {
                $this->build_query->where(['IN', 'status', [0, 1]]);
            }
        }
//        return $query;
    }

    //获取告警iview
//    public function actionGetAlerts() {
//        if (Yii::$app->request->isGet) {
//            $get = Yii::$app->request->get();
//            $alerts = AllEX::find()->select('SensorIP')->where(['>', 'created_at', $get['stime']])->andWhere(['<=', 'created_at', $get['etime']])->asArray()->all();
//            return $alerts;
//        }
//    }
}
